using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using FzWeb.Models;
using System.Text;
using System.Reflection;

namespace FzWeb.Controllers
{
    public class TestController : Controller
    {
        //
        // GET: /Test/
        public static IList<string> ignoreEntityTypes = new List<String> { "EntityReference`1",  "EntityCollection`1", "EntityState",  
                "EntityKey", "EntitySetName" };


        private BaseDataService bds = new BaseDataService();
        private PersonService personService = new PersonService();
        private CompanyService companyService = new CompanyService();
        public ActionResult Index()
        {
            return View(bds.GetNewsList());
        }

        public void TestCheckbox(string[] cb)
        {

        }
        public ActionResult Test()
        {
            return View();
        }

        public JsonResult JsonTest()
        {
            var s = JsonSerialize<Person_Resume>(personService.GetResume(50));
            return Json(s);
        }

        public ActionResult TestMenu()
        {
            return View(companyService.GetCompanyMenu());
        }

        public string JsonSerialize<T>(T obj) where T : class
        {
            var sb = new StringBuilder("{");

            var parentType = obj.GetType(); // I get type from given object 

            // use reflection to retrieve all properties of that type
            var ms = parentType.GetMembers().Where(v => v.MemberType
                == MemberTypes.Property).ToList<MemberInfo>();

            const string doubleQuote = "\"";
            var counter = 0;
            var stringTypes = new List<String> { "String", "Guid", "Boolean"};

            //Following Types are used by Entity Framework. So no need to 
            //serialize those types.

            ignoreEntityTypes.Add(parentType.Name);
            //Start iteration to navigate each property
            foreach (PropertyInfo p in ms)
            {
                counter++;
                var propertyName = p.Name;
                var propertyType = p.PropertyType;

                if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    propertyType = propertyType.GetGenericArguments()[0];
                }
                
                var propertyValue = p.GetValue(obj, null);

                //If property type is matched with ignoreTypes then
                //goto next loop
                if (ignoreEntityTypes.Contains(propertyType.Name))
                {
                    continue;
                }

                if (stringTypes.Contains(propertyType.Name))
                {
                    if (propertyValue == null)
                    {
                        sb.Append(doubleQuote + propertyName + doubleQuote + ":" + "null");
                    }

                    else
                    {
                        sb.Append(doubleQuote + propertyName + doubleQuote +
                            ":" + doubleQuote + propertyValue.ToString() + doubleQuote);
                    }
                }

                else if (propertyType != null && propertyType.IsPrimitive)
                {
                    if (propertyValue == null)
                    {
                        sb.Append(doubleQuote + propertyName + doubleQuote + ":" + "null");
                    }

                    else
                    {
                        sb.Append(doubleQuote + propertyName + doubleQuote
                            + ":" + propertyValue.ToString());
                    }
                }

                //Still I have doubt how Date Time will be handled.
                else if (propertyType.Name == "DateTime")
                {
                    if (propertyValue == null)
                    {
                        sb.Append(doubleQuote + propertyName + doubleQuote + ":" + "null");
                    }
                    else
                    {
                        var dt = (DateTime)propertyValue;
                        //sb.Append(doubleQuote + propertyName
                        //    + doubleQuote + ":"
                        //    + "new Date(" + dt.Ticks.ToString() + ")");

                        sb.Append(doubleQuote + propertyName + doubleQuote +
                                ":" + doubleQuote + dt.ToShortDateString() + doubleQuote);
                    }
                }
                else
                {
                    if (propertyValue != null)
                    {
                        sb.Append(doubleQuote + propertyType.Name + doubleQuote + ":");
                        //If property value is another entity, then
                        //call the method recursively.
                        sb.Append(JsonSerialize(propertyValue));
                    }
                    else
                    {
                        continue;
                    }
                }
                //If it is not the last property, then add comma
                if (counter < ms.Count)
                {
                    sb.Append(",");
                }
            }
            sb.Append("}");
            var result = sb.ToString().Replace(",}", "}");
            return result;
        }
    }
}
